//Learned:
//1. 用char数组创建string时，若数组中最后一个字符不是\0，则构建出来的string可能比预想的“有效长度”更长
//2. 多次write，会一次全收到吗？ --> 测试结果：不会。故要循环读或读够规定的字节数后再进行分析处理！
//3. 注意：write本质只是拷贝函数，将内容拷贝到内核的tcp缓冲区；故一定程度可以解释为什么服务器端只收到一条了：
//   当一次write将内容拷贝完成后直接就发送过去了，而在发送缓冲区的其余信息就被丢弃了！    
//4. 若发多条相同消息，客户端只读一次结果没有问题；但若要读多次，需要重新创建套接字；因为服务器端需要把fd关闭而防止客户端阻塞在read；
#include "Socket.hpp"
#include "CalServer.hpp"
#include <unistd.h>
#include <signal.h>
#include <iostream>

using std::string;
extern uint16_t DefaultPort;

class TcpServer
{
public:
    TcpServer(uint16_t port = DefaultPort)
    :_port(port)
    {}

    void InitServer()
    {
        _sock.Socket();
        _sock.Bind(_port);
        _sock.Listen();
    }

    void Start()
    {
        signal(SIGCHLD, SIG_IGN);
        signal(SIGPIPE, SIG_IGN);
        uint16_t clientport;
        string clientip;
        while(1)
        {
            int newfd = _sock.Accpet(&clientip, &clientport);
            pid_t pid = fork();
            if(pid == 0)
            {
                _sock.Close();
                while(1)
                {              
                    string in_str;
                    //while(1)
                    //{
                        char inbuffer[1280] = {0};
                        sleep(2);
                        int n = read(newfd,inbuffer,sizeof(inbuffer));
                        if(n > 0)
                        {
                            in_str += inbuffer;
                            cout << in_str;
                        }              
                        else
                        {
                            break;
                        }              
                   //}
           
                    string package = in_str;

                    //处理收到的报文
                    CalServer cs;
                    log(Debug,"debug:\n%s", package.c_str());
                    cout << "package len is " << package.size() << endl;

                    while(1)
                    {
                        log(Debug,"debug:\n%s", package.c_str());
                        string res = cs.Calculator(package);     
                        if(res == "") 
                        {
                            close(newfd);
                            break;
                        }

                        log(Debug,"debug:\n%s", res.c_str());
                        int n = write(newfd, res.c_str(), res.size());          
                        if(n <= 0)  break;
                        sleep(1);                              
                    } 
                    sleep(1);
                } 
                exit(0);
            }
            close(newfd);          
            sleep(1);  
        }
    }

private:
    Sock _sock;
    uint16_t _port;
    string _ip;
};

